#include <autoconfig.h>
// #include "fpga-tr700.h"
#include "port.h"
#include "fpga-common.h"
#include "encode-otdr.h"
// #include "fpga-otdr-cfg.h"
#include <string.h>
#include <assert.h>

#ifdef __cplusplus
extern "C" {
#endif
short _encode_laser(struct fpga_test_param *val)
{
    return val->laser_ch;
}


/*
 * 量程（km） 0.3          1            2      5    ...    300          400
 * 编码      300         0x8000+1  0x8000+2  0x8000+5    0x8000+300  0x8000+400
 *          (十进制)     十六进制
 */
short _encode_pulse(struct fpga_test_param *val)
{
    // switch (val->pulse) {
    // case 5:
    // 	return val->pulse;
    // case 10:
    // 	return val->pulse;
    // }

    if (val->pulse < 20) {
	return val->pulse;
    }
    return 0x8000 + val->pulse / 20;
}

short _encode_dist(struct fpga_test_param *val)
{

    if (val->dist == 300) {
	return val->dist;
    }

    return 0x8000 + val->dist / 1000;
}


short _encode_self_pulse(struct fpga_test_param *val)
{
    return val->pulse;
}


short _encode_self_dist(struct fpga_test_param *val)
{
    return val->dist;
}


// **************************************************************************


char _encode_adopt(struct fpga_test_param *val)
{
    switch (val->adopt_pt) {
    case 32000:
	return 8;
	break;
    case 4000:
	return 1;
	break;
    case 8000:
	return 2;
	break;
    case 16000:
	return 4;
	break;
    case 64000:
	return 16;
	break;
    case 128000:
	return 32;
	break;
    case 256000:
	return 64;
	break;
    }
    return 8;
}

short _encode_add_cnt(struct fpga_test_param *val)
{
    return val->add_cnt;
}


char _encode_amp(struct fpga_test_param *val)
{
    // 限制在5个可控档位以内
    char b0, b1, b2, b3, b4, b5, b6, b7;  // 各比特位
    char level;
    char encode_lv1 = 0, encode_lv2 = 0, encode_lv3 = 0, encode_lv4 = 0;
    char encode = 0;

#if AMP_MASK_LV1
    level = val->amp & 0xff;
    b0    = (level & 0x01) ? AMP_B0_TO_SW : 0;
    b1    = (level & 0x02) ? AMP_B1_TO_SW : 0;
    b2    = (level & 0x04) ? AMP_B2_TO_SW : 0;
    b3    = (level & 0x08) ? AMP_B3_TO_SW : 0;
    b4    = (level & 0x10) ? AMP_B4_TO_SW : 0;
    b5    = (level & 0x20) ? AMP_B5_TO_SW : 0;
    b6    = (level & 0x40) ? AMP_B6_TO_SW : 0;
    b7    = (level & 0x80) ? AMP_B7_TO_SW : 0;

#if (AMP_LOW_ACTIVE_LV1 == 1)
    encode_lv1 = ~(b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);  // 硬件高电平有效
#else
    encode_lv1 = (b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);  // 硬件低电平有效
#endif
    encode_lv1 &= AMP_MASK_LV1;  // 去掉无用 bit
#endif                           // end AMP_MASK_LV1


#if AMP_MASK_LV2
    level = (val->amp >> 8) & 0xff;
    b0    = (level & 0x01) ? AMP_B8_TO_SW : 0;
    b1    = (level & 0x02) ? AMP_B9_TO_SW : 0;
    b2    = (level & 0x04) ? AMP_B10_TO_SW : 0;
    b3    = (level & 0x08) ? AMP_B11_TO_SW : 0;
    b4    = (level & 0x10) ? AMP_B12_TO_SW : 0;
    b5    = (level & 0x20) ? AMP_B13_TO_SW : 0;
    b6    = (level & 0x40) ? AMP_B14_TO_SW : 0;
    b7    = (level & 0x80) ? AMP_B15_TO_SW : 0;
#if (AMP_LOW_ACTIVE_LV2 == 1)
    encode_lv2 = ~(b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);
#else
    encode_lv2 = (b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);
#endif
    encode_lv2 &= AMP_MASK_LV2;
#endif  // end AMP_MASK_LV2


#if AMP_MASK_LV3
    level = (val->amp >> 16) & 0xff;
    b0    = (level & 0x01) ? AMP_B16_TO_SW : 0;
    b1    = (level & 0x02) ? AMP_B17_TO_SW : 0;
    b2    = (level & 0x04) ? AMP_B18_TO_SW : 0;
    b3    = (level & 0x08) ? AMP_B19_TO_SW : 0;
    b4    = (level & 0x10) ? AMP_B20_TO_SW : 0;
    b5    = (level & 0x20) ? AMP_B21_TO_SW : 0;
    b6    = (level & 0x40) ? AMP_B22_TO_SW : 0;
    b7    = (level & 0x80) ? AMP_B23_TO_SW : 0;
#if (AMP_LOW_ACTIVE_LV3 == 1)
    encode_lv3 = ~(b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);
#else
    encode_lv3 = (b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);
#endif
    encode_lv3 &= AMP_MASK_LV3;
#endif  // end AMP_MASK_LV3


#if AMP_MASK_LV4
    level = (val->amp >> 24) & 0xff;
    b0    = (level & 0x01) ? AMP_B24_TO_SW : 0;
    b1    = (level & 0x02) ? AMP_B25_TO_SW : 0;
    b2    = (level & 0x04) ? AMP_B26_TO_SW : 0;
    b3    = (level & 0x08) ? AMP_B27_TO_SW : 0;
    b4    = (level & 0x10) ? AMP_B28_TO_SW : 0;
    b5    = (level & 0x20) ? AMP_B29_TO_SW : 0;
    b6    = (level & 0x40) ? AMP_B30_TO_SW : 0;
    b7    = (level & 0x80) ? AMP_B31_TO_SW : 0;

#if (AMP_LOW_ACTIVE_LV4 == 1)
    encode_lv4 = ~(b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);
#else
    encode_lv4 = (b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);
#endif
    encode_lv4 &= AMP_MASK_LV4;
#endif  // end AMP_MASK_LV4

    encode = (encode_lv1 + encode_lv2 + encode_lv3 + encode_lv4) &
             (AMP_MASK_LV1 + AMP_MASK_LV2 + AMP_MASK_LV3 + AMP_MASK_LV4);

    return encode;
}


//**************************************************************
// 有效参数等待 FPGA 解释
// 未必是下面的有效值

#define APD_LOW_ACTIVE (CFG_APD_LOW_ACTIVE)  // 光耦开关低电平有效
#define APD_LOW_ACTIVE (CFG_APD_LOW_ACTIVE)
#define APD_LOW_ACTIVE (CFG_APD_LOW_ACTIVE)
#define APD_LOW_ACTIVE (CFG_APD_LOW_ACTIVE)


#define APD_B0_TO_SW   (CFG_APD_B0_TO_SW)  // bit0 映射到APD编码值 0x80上
#define APD_B1_TO_SW   (CFG_APD_B1_TO_SW)
#define APD_B2_TO_SW   (CFG_APD_B2_TO_SW)
#define APD_B3_TO_SW   (CFG_APD_B3_TO_SW)
#define APD_B4_TO_SW   (CFG_APD_B4_TO_SW)
#define APD_B5_TO_SW   (CFG_APD_B5_TO_SW)
#define APD_B6_TO_SW   (CFG_APD_B6_TO_SW)
#define APD_B7_TO_SW   (CFG_APD_B7_TO_SW)

#define APD_MASK       (CFG_APD_MASK)

char _encode_apd_vol(struct fpga_test_param *val)
{
    char b0, b1, b2, b3, b4, b5, b6, b7;  // 各比特位
    char level;
    char encode = 0;

#if APD_MASK
    level = val->apd_vol & 0xff;
    b0    = (level & 0x01) ? APD_B0_TO_SW : 0;
    b1    = (level & 0x02) ? APD_B1_TO_SW : 0;
    b2    = (level & 0x04) ? APD_B2_TO_SW : 0;
    b3    = (level & 0x08) ? APD_B3_TO_SW : 0;
    b4    = (level & 0x10) ? APD_B4_TO_SW : 0;
    b5    = (level & 0x20) ? APD_B5_TO_SW : 0;
    b6    = (level & 0x40) ? APD_B6_TO_SW : 0;
    b7    = (level & 0x80) ? APD_B7_TO_SW : 0;

#if (APD_LOW_ACTIVE == 1)
    encode = ~(b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);  // 硬件高电平有效
#else
    encode     = (b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7);  // 硬件低电平有效
#endif
    encode &= APD_MASK;  // 去掉无用 bit
#endif                   // end APD_LOW_ACTIVE

    return encode;
}

char _list_power[] = {
    0,
    OTDR_LASER_PW_LV1,
    OTDR_LASER_PW_LV2,
    OTDR_LASER_PW_LV3,
    OTDR_LASER_PW_LV4,
};
char _encode_power(struct fpga_test_param *val)
{
    // printf("power %d\r\n", val->power);
    // assert(val->power < ARRAY_SIZE(_list_power));
    // assert(0 <= val->power);

    return _list_power[(unsigned long)val->power];
}
char _encode_slot(struct fpga_test_param *val)
{
    // PRINTD("do nothing");
#if defined(CONFIG_EN_CAP)
    return val->cap;
#else
    return 0;
#endif
}
char _encode_ch(struct fpga_test_param *val)
{
    // PRINTD("do nothing");
    return val->panel_ch;
}

unsigned short _encode_add_ms(struct fpga_test_param *val)
{
    return val->add_ms;
}

#define FREQ_OFFSET     (12)
#define ADOPT_PT_OFFSET (14)

unsigned long _decode_freq(char *rbuf)
{
    unsigned short section;
    memcpy(&section, rbuf + FREQ_OFFSET, sizeof(unsigned short));
    switch (section) {
    case 12:
	return 12500000;
    case 6:
	return 6250000;
    default:
	break;
    }
    return section * 1000000;
}
unsigned short _decode_adopt_pt(char *rbuf)
{
    unsigned short section;
    memcpy(&section, rbuf + ADOPT_PT_OFFSET, sizeof(unsigned short));
    return section * 1000;
}

#ifdef __cplusplus
}
#endif
